package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.base.PageResponse;
import com.zzyl.dto.CustomerUserLoginDto;
import com.zzyl.entity.Contract;
import com.zzyl.entity.Elder;
import com.zzyl.entity.Member;
import com.zzyl.entity.Order;
import com.zzyl.exception.BusinessException;
import com.zzyl.mapper.ContractMapper;
import com.zzyl.mapper.ElderMapper;
import com.zzyl.mapper.MemberMapper;
import com.zzyl.mapper.OrderMapper;
import com.zzyl.properties.JwtProperties;
import com.zzyl.properties.WechatConfigProperties;
import com.zzyl.service.MemberService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.LoginVo;
import com.zzyl.vo.MemberVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {
    //默认昵称
    private static List<String> DEFAULT_NICKNAME_PREFIX = List.of("生活更美好", "大桔大利", "日富一日", "好柿开花", "柿柿如意", "一椰暴富", "大柚所为", "杨梅吐气", "天生荔枝");
    @Autowired
    private ContractMapper contractMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private WechatConfigProperties wechatConfigProperties;

    @Autowired
    private JwtProperties jwtProperties;

    @Override
    public LoginVo login(CustomerUserLoginDto dto) {
        //1.向微信官方发请求 获取openid
        Map<String,Object>map=new HashMap<>();
        map.put("appid",wechatConfigProperties.getAppid());
        map.put("secret",wechatConfigProperties.getSecret());
        map.put("js_code",dto.getCode());
        map.put("grant_type","authorization_code");
        String result = HttpUtil.get("https://api.weixin.qq.com/sns/jscode2session", map);
        //JSON字符串转换成hashmap 获取其中openid的键值对
        HashMap<String,String> hashMap = JSON.parseObject(result, HashMap.class);
        String openid=hashMap.get("openid");
        if (StrUtil.isEmpty(openid)){
            throw new BusinessException("微信登录失败");
        }
        //2.从微信官方获得token
        Map<String,Object>map1=new HashMap<>();
        map1.put("appid",wechatConfigProperties.getAppid());
        map1.put("secret",wechatConfigProperties.getSecret());
        map1.put("grant_type","client_credential");
        String result1 = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", map1);
        HashMap<String,String> hashMap1 = JSON.parseObject(result1, HashMap.class);
        String accessToken = hashMap1.get("access_token");
        if (StrUtil.isEmpty(accessToken)){
            throw new BusinessException("微信登录失败");
        }
        //3.从微信官方处通过token获取phone
        Map<String,Object>map2=new HashMap<>();
        map2.put("code",dto.getPhoneCode());
        String result2 = HttpUtil.post("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+accessToken, JSON.toJSONString(map2));
        JSONObject jsonObject = JSON.parseObject(result2);
        String phoneNumber = jsonObject.getJSONObject("phone_info").getString("phoneNumber");
        //4.判断member表中是否存在openid 不存在就保存openid 存在就更新phone
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Member::getOpenId,openid);
        Member member=getBaseMapper().selectOne(wrapper);
        if (member==null){
            //直接赋值会出现空指针异常 所以先创建一个member对象
            member=new Member();
            member.setOpenId(openid);
            member.setPhone(phoneNumber);
            //随机昵称前缀+手机后四位 substring包头不包尾
            member.setName(RandomUtil.randomEle(DEFAULT_NICKNAME_PREFIX)+phoneNumber.substring(7,11));
            getBaseMapper().insert(member);
        }else {
            member.setPhone(phoneNumber);
            getBaseMapper().updateById(member);
        }

        //5.获取openid后 用openid生成token返回给前端
        //创建有效载荷
        Map<String,Object>claims=new HashMap<>();
        //有效载荷包括id和昵称
        claims.put("userid",member.getId());
        claims.put("sub",member.getName());
        String token = JwtUtil.createJWT(jwtProperties.getBase64EncodedSecretKey(), jwtProperties.getTtl(), claims);

        //封装vo
        LoginVo loginVo=new LoginVo();
        loginVo.setToken(token);
        loginVo.setNickName(member.getName());

        return loginVo;
    }

    @Override
    public PageResponse<MemberVo> findByPage(String nickname, String phone, Integer pageNum, Integer pageSize) {
        //创建分页对象
        Page<Member>page=new Page<>(pageNum,pageSize);
        //1.先条件查询出member中的属性
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StrUtil.isNotEmpty(nickname), Member::getName, nickname)
                .like(StrUtil.isNotEmpty(phone), Member::getPhone, phone);
        page=getBaseMapper().selectPage(page,wrapper);
        //2. 遍历page.Records, 将得到每一个member对象转换成membervo
        List<MemberVo>memberVoList=page.getRecords().stream().map(member -> {
            //2.1将之前查询到的member数据复制给membervo
            MemberVo memberVo= BeanUtil.copyProperties(member,MemberVo.class);
            //2.2查询老人姓名
            //2.2.1两表查询elder和app_member_elder连接条件elder.id=ame.elderid 查询条件memberid=#{}
            List<Elder>list=elderMapper.getByMemberId(memberVo.getId());
            if (CollUtil.isNotEmpty(list)){
                //2.2.2收集老人姓名
                memberVo.setElderNames(list.stream().map(elder -> elder.getName()).collect(Collectors.joining(",")));
            }
            //3. 是否签约
            LambdaQueryWrapper<Contract> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Contract::getMemberPhone,memberVo.getPhone())
                    .eq(Contract::getStatus,1);
            Long count = contractMapper.selectCount(wrapper1);
            memberVo.setIsSign(count>0?"是":"否");
            //4. 下单次数
            LambdaQueryWrapper<Order> wrapper2 = new LambdaQueryWrapper<>();
            wrapper2.eq(Order::getMemberId,memberVo.getId())
                    .eq(Order::getStatus,3);
            Long count1 = orderMapper.selectCount(wrapper2);
            memberVo.setOrderCount(count1.intValue());
            return memberVo;
        }).collect(Collectors.toList());
        //返回结果
        return new PageResponse<>(page,memberVoList);
    }
}
